/**
 * 所有版权归 广西梧州 陈锦韬 所有
 *
 * @Title: StockService
 * @Package com.rx.stock.service
 * @Description: 股票服务
 * @author: 陈锦韬
 * @date: 2021\9\9 0009
 * @version V1.0
 * @Copyright: 2021 陈锦韬  All rights reserved.
 */
package com.rx.stock.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rx.core.base.RxBaseConstant;
import com.rx.core.base.RxBaseData;
import com.rx.core.base.RxBaseException;
import com.rx.core.enm.HANDLER_TYPE;
import com.rx.core.enm.RX_LOG_MODE;
import com.rx.core.enm.RX_STATUS;
import com.rx.core.iface.InputMode;
import com.rx.core.iface.ReturnInputMode;
import com.rx.core.service.RxBaseAbstractService;
import com.rx.core.service.StandardService;
import com.rx.core.util.EmptyChecker;
import com.rx.core.util.HttpClientUtil;
import com.rx.core.util.RxUtil;
import com.rx.stock.eum.DIRECT_FLG;
import com.rx.stock.eum.MAX_FLG;
import com.rx.stock.eum.MAX_TYPE;
import com.rx.stock.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: Administrator
 * @Description: 股票服务
 * @date: 2021\9\9 0009
 */
@Service
@Slf4j
public class StockService extends RxBaseAbstractService {


    public static final int MON_TRN_DAY = 22;



    @Autowired
    StandardService standardService;

    @Autowired
    AsyncTask asyncTask;

    @Value("${rx.stock.licence:A456630F6FFFDA6CEB3D819F0C2D5528B321}")
    private String rxStockLicence;
    @Value("${rx.stock.min.change.rate:0.2}")
    private String minChangeRate;

    private void updateShareInfo(){
        String requestUrl = "http://jk791.com/stock/info/queryStockList";
        Map<String, String> requestUrlParam = new HashMap<>();
        //licence
        requestUrlParam.put("licence", rxStockLicence);
        //发送post请求读取调用微信接口获取openid用户唯一标识
        //发送post请求读取调用微信接口获取openid用户唯一标识{"dm":"000001","jys":"sz","mz":"平安银行"}
        String json = HttpClientUtil.doGet(requestUrl, requestUrlParam);
        //String json = "[{\"dm\":\"000001\",\"jys\":\"sz\",\"mz\":\"平安银行\"},{\"dm\":\"000002\",\"jys\":\"sz\",\"mz\":\"万 科Ａ\"},{\"dm\":\"000004\",\"jys\":\"sz\",\"mz\":\"国华网安\"},{\"dm\":\"000005\",\"jys\":\"sz\",\"mz\":\"ST星源\"},{\"dm\":\"000006\",\"jys\":\"sz\",\"mz\":\"深振业Ａ\"}]";
        log.info("json:" + json);
        List<NetShareInfo> list = JSONArray.parseArray(json, NetShareInfo.class);
        if(EmptyChecker.isEmpty(list)){
            return;
        }
        List<RxBaseData> stockShareInfoList = new ArrayList<>();
        for (NetShareInfo netShareInfo : list) {
            stockShareInfoList.add(netShareInfo.createStockShareInfo());
        }
        try {
            // 查询所有股票
            RxBaseData conditionForQuery = RxBaseData.create(StockShareInfo.class, HANDLER_TYPE.SINGLE_LIST);
            Object object = standardService.searchList(conditionForQuery);
            if (object instanceof List){
                List<StockShareInfo> haveInDbList = (ArrayList<StockShareInfo>)object;
                Map<String,StockShareInfo> map = haveInDbList.stream().collect(Collectors.toMap(StockShareInfo::getShareCode,o->o));
                for (RxBaseData rxBaseData : stockShareInfoList) {
                    StockShareInfo netShareInfo = (StockShareInfo)rxBaseData;
                    StockShareInfo fromDb = map.get(netShareInfo.getShareCode());
                    if(EmptyChecker.notEmpty(fromDb)){
                        netShareInfo.setBid(fromDb.getBid());
                        netShareInfo.setVer(fromDb.getVer());
                    }
                }
            }

            RxBaseData condition = RxBaseData.create(StockShareInfo.class, HANDLER_TYPE.SINGLE_BATCH_SAVE);
            condition.setDataList(stockShareInfoList);
            standardService.batchSave(condition);

        } catch (IllegalAccessException | InstantiationException e)  {
            log.info(e.getMessage());
        }
    }

    private String getShareLatestJson(String shareCode){
        String requestUrl = "http://jk791.com/stock/shishi/queryShishiStockInfo";
        Map<String, String> requestUrlParam = new HashMap<>();
        //licence
        requestUrlParam.put("licence", rxStockLicence);
        requestUrlParam.put("stockCodes", shareCode);

        String json = HttpClientUtil.doGet(requestUrl, requestUrlParam);
        //String json = "[{\"dm\":\"000001\",\"jys\":\"sz\",\"mz\":\"平安银行\"},{\"dm\":\"000002\",\"jys\":\"sz\",\"mz\":\"万 科Ａ\"},{\"dm\":\"000004\",\"jys\":\"sz\",\"mz\":\"国华网安\"},{\"dm\":\"000005\",\"jys\":\"sz\",\"mz\":\"ST星源\"},{\"dm\":\"000006\",\"jys\":\"sz\",\"mz\":\"深振业Ａ\"}]";
        log.info("today json:" + json);
        return json;
    }

    /**
     * 最新
     * @param shareCode
     * @return
     */
    private String getShareHistoryJson(String shareCode){
        String requestUrl = "http://jk791.com/stock/history/queryDayStockHistoryInfo";
        Map<String, String> requestUrlParam = new HashMap<>();
        //http://jk791.com/stock/history/queryDayStockHistoryInfo?licence=A456630F6FFFDA6CEB3D819F0C2D5528B321&periodType=day&fuquanType=before&stockCode=000001
        requestUrlParam.put("licence", rxStockLicence);
        requestUrlParam.put("periodType", "day");
        requestUrlParam.put("fuquanType", "before");
        requestUrlParam.put("stockCode", shareCode);

        String json = HttpClientUtil.doGet(requestUrl, requestUrlParam);
        //String json = "[{\"dm\":\"000001\",\"jys\":\"sz\",\"mz\":\"平安银行\"},{\"dm\":\"000002\",\"jys\":\"sz\",\"mz\":\"万 科Ａ\"},{\"dm\":\"000004\",\"jys\":\"sz\",\"mz\":\"国华网安\"},{\"dm\":\"000005\",\"jys\":\"sz\",\"mz\":\"ST星源\"},{\"dm\":\"000006\",\"jys\":\"sz\",\"mz\":\"深振业Ａ\"}]";
        log.info("history json:" + json);
        return json;
    }

    private String getShareHistoryJsonFromDF(StockShareInfo stockShareInfo,boolean yesNow){
        String requestUrl = "https://push2his.eastmoney.com/api/qt/stock/kline/get";
        Map<String, String> requestUrlParam = new HashMap<>();
        requestUrlParam.put("fields1", "f1,f2,f3,f4,f5,f6");
        requestUrlParam.put("fields2", "f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61");
        requestUrlParam.put("ut", "b2884a393a59ad64002292a3e90d46a5");
        requestUrlParam.put("klt", "101");
        requestUrlParam.put("fqt", "1");
        String secid ;
        if ("sz".equalsIgnoreCase(stockShareInfo.getLocationCode())){
            secid = "0." + stockShareInfo.getShareCode();
        }else {
            secid = "1." + stockShareInfo.getShareCode();
        }

        requestUrlParam.put("secid", secid);

        Date now  = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        String nowString = formatter.format(now);
        if (yesNow){
            requestUrlParam.put("beg",nowString);
            requestUrlParam.put("end",nowString);
//            requestUrlParam.put("beg","20220318");
//            requestUrlParam.put("end","20220318");
        }else {
            Calendar calendar=Calendar.getInstance();
            calendar.add(Calendar.DATE,-1);
            requestUrlParam.put("beg","20200101");
            requestUrlParam.put("end",formatter.format(calendar.getTime()));
        }



        String json = HttpClientUtil.doGet(requestUrl, requestUrlParam);
        //String json = "[{\"dm\":\"000001\",\"jys\":\"sz\",\"mz\":\"平安银行\"},{\"dm\":\"000002\",\"jys\":\"sz\",\"mz\":\"万 科Ａ\"},{\"dm\":\"000004\",\"jys\":\"sz\",\"mz\":\"国华网安\"},{\"dm\":\"000005\",\"jys\":\"sz\",\"mz\":\"ST星源\"},{\"dm\":\"000006\",\"jys\":\"sz\",\"mz\":\"深振业Ａ\"}]";
        log.info("DF history json:" + json);
        return json;
    }
    /**
     * 更新股票历史数据
     */
    private void updateShareTradeHistory(){
        StockShareInfo conditionForQuery = null;
        try {
            conditionForQuery = (StockShareInfo)RxBaseData.create(StockShareInfo.class, HANDLER_TYPE.SINGLE_LIST);
            Object object = standardService.searchList(conditionForQuery);
            if (object instanceof List){
                List<StockShareInfo> haveInDbList = (ArrayList<StockShareInfo>)object;
                for (StockShareInfo stockShareInfo : haveInDbList) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {

                    }
                    String json = getShareHistoryJson(stockShareInfo.getShareCode());
                    List<NetHiShareInfo> list = JSONArray.parseArray(json, NetHiShareInfo.class);
                    if(EmptyChecker.isEmpty(list)){
                        continue;
                    }
                    List<RxBaseData> stockShareInfoList = new ArrayList<>();
                    for (NetHiShareInfo netShareInfo : list) {
                        StockHistoryInfo stockShareInfo1 = netShareInfo.createStockShareInfo();
                        stockShareInfo1.setShareCode(stockShareInfo.getShareCode());
                        stockShareInfo1.setStatus(RX_STATUS.NORMAL.getCode());
                        stockShareInfoList.add(stockShareInfo1);
                    }

                    // 查询所有股票
                    StockHistoryInfo historyInfo = (StockHistoryInfo)RxBaseData.create(StockHistoryInfo.class, HANDLER_TYPE.SINGLE_LIST);
                    historyInfo.setShareCode(stockShareInfo.getShareCode());
                    Object historyResult = standardService.searchList(historyInfo);
                    if (historyResult instanceof List){
                        List<StockHistoryInfo> historyFromDb = (ArrayList<StockHistoryInfo>)historyResult;
                        Map<String,StockHistoryInfo> map = historyFromDb.stream().collect(Collectors.toMap(o->{
                            return o.getShareCode() + o.getTradeTime().toString();
                        },o->o));
                        for (RxBaseData rxBaseData : stockShareInfoList) {
                            StockHistoryInfo netShareInfo = (StockHistoryInfo)rxBaseData;
                            StockHistoryInfo fromDb = map.get(netShareInfo.getShareCode() + netShareInfo.getTradeTime().toString());
                            if(EmptyChecker.notEmpty(fromDb)){
                                netShareInfo.setBid(fromDb.getBid());
                                netShareInfo.setVer(fromDb.getVer());
                            }
                        }
                    }

                    RxBaseData condition = RxBaseData.create(StockHistoryInfo.class, HANDLER_TYPE.SINGLE_BATCH_SAVE);
                    condition.setDataList(stockShareInfoList);
                    standardService.batchSave(condition);
                }
            }

        } catch (IllegalAccessException | InstantiationException e) {
            e.printStackTrace();
        }
    }

    private BigDecimal initAvgPrice(List<StockHistoryInfo> historyFromDb,int dayCount){
        BigDecimal fiveAvg = BigDecimal.ZERO;
        int size = historyFromDb.size();
        int i = 0;
        if (size < dayCount){
           return null;
        }
        for(;i<dayCount;i++){
            StockHistoryInfo historyInfo1 = historyFromDb.get(i);
            fiveAvg = RxUtil.Amount.add(fiveAvg,historyInfo1.getClosePrice());
        }
        fiveAvg = RxUtil.Amount.divideRound(fiveAvg,dayCount,3);
        return fiveAvg;
    }
    private BigDecimal initAvgVolunm(List<StockHistoryInfo> historyFromDb,int dayCount){
        BigDecimal fiveAvg = BigDecimal.ZERO;
        int size = historyFromDb.size();
        int i = 0;
        if (size < dayCount){
            return null;
        }
        for(;i<dayCount;i++){
            StockHistoryInfo historyInfo1 = historyFromDb.get(i);
            fiveAvg = RxUtil.Amount.add(fiveAvg,historyInfo1.getTurnOver());
        }
        return RxUtil.Amount.divideRound(fiveAvg,dayCount,3);
    }
    private BigDecimal initAvgSwitchRate(List<StockHistoryInfo> historyFromDb,int dayCount){
        BigDecimal switchRateAvg = BigDecimal.ZERO;
        int size = historyFromDb.size();
        int i = 0;
        if (size < dayCount){
            return null;
        }
        for(;i<dayCount;i++){
            StockHistoryInfo historyInfo1 = historyFromDb.get(i);
            switchRateAvg = RxUtil.Amount.add(switchRateAvg,historyInfo1.getSwitchRate());
        }
        return RxUtil.Amount.divideRound(switchRateAvg,dayCount,3);
    }
    private BigDecimal getAvgByDayCount(StockHistoryInfo old,int dayCount){
        BigDecimal oldAvg = BigDecimal.ZERO;
        if (dayCount == 5){
            oldAvg = old.getFiveAvg();
        }else if (dayCount == 13){
            oldAvg = old.getThirteenAvg();
        }if (dayCount == 21){
            oldAvg = old.getTwentyOneAvg();
        }
        return oldAvg;
    }
    private BigDecimal assignAvg(List<StockHistoryInfo> historyFromDb,StockHistoryInfo old,int dayCount,int i){
        int indexLast = i + dayCount - 1;
        BigDecimal oldAvg = getAvgByDayCount(old,dayCount);
        if (EmptyChecker.notEmpty(oldAvg) && indexLast < historyFromDb.size()){
            BigDecimal diffAmount = RxUtil.Amount.subtract(historyFromDb.get(indexLast).getClosePrice(),old.getClosePrice());
            BigDecimal divide = RxUtil.Amount.divideRound(diffAmount,dayCount,3);
            return RxUtil.Amount.add(oldAvg,divide);
        }
        return BigDecimal.ZERO;
    }
    private List<RxBaseData> assignAvg(List<StockHistoryInfo> historyFromDb,StockShareInfo stockShareInfo,List<StockHistoryInfo> newHistoryList){
        BigDecimal fiveAvg = initAvgPrice(historyFromDb,5);
        BigDecimal thirTeenAvg = initAvgPrice(historyFromDb,13);
        BigDecimal twentyOneAvg = initAvgPrice(historyFromDb,21);
        BigDecimal fiftyAvg = initAvgVolunm(historyFromDb,50);
        BigDecimal avgSwitch = initAvgSwitchRate(historyFromDb,stockShareInfo.getThirteenParam());

        List<RxBaseData> stockShareInfoList = new ArrayList<>();
        int i = 1;
        int size = historyFromDb.size();
        StockHistoryInfo old = historyFromDb.get(0);
        old.setFiveAvg(fiveAvg);
        old.setThirteenAvg(thirTeenAvg);
        old.setTwentyOneAvg(twentyOneAvg);
        old.setFiftyAvg(fiftyAvg);
        old.setAvgSwitch(avgSwitch);
        stockShareInfoList.add(old);
        if (null != newHistoryList){
            newHistoryList.add(old);
        }
        for(;i<size;i++){
            StockHistoryInfo stockHistoryInfo = historyFromDb.get(i);
            stockHistoryInfo.setFiveAvg(assignAvg(historyFromDb,old,5,i));
            stockHistoryInfo.setThirteenAvg(assignAvg(historyFromDb,old,13,i));
            stockHistoryInfo.setTwentyOneAvg(assignAvg(historyFromDb,old,21,i));

            stockHistoryInfo.setFiftyAvg(BigDecimal.ZERO);
            if (EmptyChecker.notEmpty(old.getFiftyAvg()) && i + 49 < historyFromDb.size()){
                BigDecimal diffAmount = RxUtil.Amount.subtract(historyFromDb.get(i + 49).getTurnOver(),old.getTurnOver());
                BigDecimal divide = RxUtil.Amount.divideRound(diffAmount,50,3);
                stockHistoryInfo.setFiftyAvg(RxUtil.Amount.add(old.getFiftyAvg(),divide));
            }
            int avgIndex = i + stockShareInfo.getThirteenParam() - 1;
            stockHistoryInfo.setAvgSwitch(BigDecimal.ZERO);
            if (EmptyChecker.notEmpty(old.getAvgSwitch()) &&  avgIndex < historyFromDb.size()){
                BigDecimal diffAmount = RxUtil.Amount.subtract(historyFromDb.get(avgIndex).getSwitchRate(),old.getSwitchRate());
                BigDecimal divide = RxUtil.Amount.divideRound(diffAmount,stockShareInfo.getThirteenParam(),3);
                stockHistoryInfo.setAvgSwitch(RxUtil.Amount.add(old.getAvgSwitch(),divide));
            }
            stockHistoryInfo.setDiffSwitch(RxUtil.Amount.subtract(stockHistoryInfo.getSwitchRate(),old.getSwitchRate()));
            stockShareInfoList.add(stockHistoryInfo);
            if (null != newHistoryList){
                newHistoryList.add(stockHistoryInfo);
            }
            old = stockHistoryInfo;
        }
        return stockShareInfoList;
    }
    /**
     * 更新均线数据
     */
    private void updateShareAvg(){

        dealOneShare(info->{
            StockShareInfo stockShareInfo = (StockShareInfo)info;
            dealOneShareHistory(stockShareInfo,stock->{
                List<StockHistoryInfo> historyFromDb = (List<StockHistoryInfo>)stock;
                return assignAvg(historyFromDb,stockShareInfo,null);
            });
        });
    }


    public void dealOneShare(InputMode inputMode){
        StockShareInfo conditionForQuery = null;
        try {
            conditionForQuery = (StockShareInfo)RxBaseData.create(StockShareInfo.class, HANDLER_TYPE.SINGLE_LIST);
            conditionForQuery.setStatus(RX_STATUS.NORMAL.getCode());
            Object object = standardService.searchList(conditionForQuery);
            if (object instanceof List){
                List<StockShareInfo> haveInDbList = (ArrayList<StockShareInfo>)object;
                haveInDbList = haveInDbList.stream().sorted(Comparator.comparing(StockShareInfo::getShareCode)).collect(Collectors.toList());
                for (StockShareInfo stockShareInfo : haveInDbList) {
                    // 查询所有股票历史数据
                    log.info(RX_LOG_MODE.DEFAULT.getFormat("股票代码【{}】,股票名称【{}】"),"股票信息",stockShareInfo.getShareCode(),stockShareInfo.getShareName());
                    try{
                        inputMode.handle(stockShareInfo);
                    }catch (Throwable e){

                        StockShareInfo conditionForUpdate = (StockShareInfo)RxBaseData.create(StockShareInfo.class, HANDLER_TYPE.SINGLE_UPDATE);
                        conditionForUpdate.setBid(stockShareInfo.getBid());
                        conditionForUpdate.setValid(RX_STATUS.FROZEN.getCode());
                        standardService.update(conditionForUpdate);
                    }

                }
            }

        } catch (IllegalAccessException | InstantiationException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取股票的历史信息
     */

    private List<StockHistoryInfo> getHistoryList(Date date,String shareCode,boolean reverse){
        StockHistoryInfo historyInfo = null;
        try {
            historyInfo = (StockHistoryInfo) RxBaseData.create(StockHistoryInfo.class, HANDLER_TYPE.SINGLE_LIST);

            if (EmptyChecker.notEmpty(date)){
                historyInfo.setTradeTime(date);
            }
            if (EmptyChecker.notEmpty(shareCode)){
                historyInfo.setShareCode(shareCode);
            }

            Object historyResult = standardService.searchList(historyInfo);

            if (!(historyResult instanceof List)){
                return  new ArrayList<>();
            }else{
                List<StockHistoryInfo> historyFromDb = (ArrayList<StockHistoryInfo>)historyResult;
                if (reverse){
                    return historyFromDb.stream().sorted(Comparator.comparing(StockHistoryInfo::getTradeTime).reversed()).collect(Collectors.toList());
                }
                return  historyFromDb;
            }
        } catch (IllegalAccessException | InstantiationException e) {
            if (EmptyChecker.notEmpty(shareCode)){
                log.error(RX_LOG_MODE.DEFAULT.getFormat(shareCode),"获取历史数据失败");
            }
            if (EmptyChecker.notEmpty(date)){
                SimpleDateFormat formatter = new SimpleDateFormat(RxBaseConstant.DATE_FORMAT_DATEONLY);
                String nowString = formatter.format(date);
                log.error(RX_LOG_MODE.DEFAULT.getFormat(nowString),"获取历史数据失败");
            }
        }
        return new ArrayList<>();
    }

    private void dealOneShareHistory(StockShareInfo stockShareInfo,ReturnInputMode inputMode){
        try {
            List<StockHistoryInfo> historyFromDb = getHistoryList(null,stockShareInfo.getShareCode(),true);
            log.info(RX_LOG_MODE.DEFAULT.getFormat("列表处理前"));
            List<RxBaseData> stockShareInfoList = (List<RxBaseData>)inputMode.handle(historyFromDb);
            log.info(RX_LOG_MODE.DEFAULT.getFormat("批量保存"));
            RxBaseData condition = RxBaseData.create(StockHistoryInfo.class, HANDLER_TYPE.SINGLE_BATCH_UPDATE);
            condition.setDataList(stockShareInfoList);
            standardService.batchSave(condition);
        } catch (IllegalAccessException|InstantiationException| RxBaseException e) {
            log.error("error：dealOneShareHistory");
            log.error(RX_LOG_MODE.DEFAULT.getFormat("股票代码【{}】,股票名称【{}】"),"股票信息",stockShareInfo.getShareCode(),stockShareInfo.getShareName());
        }
    }

    private void dealOneShareMax(StockShareInfo stockShareInfo,String type,ReturnInputMode inputMode){
        try {
            StockMaxInfo stockMaxInfo = (StockMaxInfo)RxBaseData.create(StockMaxInfo.class, HANDLER_TYPE.SINGLE_LIST);
            stockMaxInfo.setShareCode(stockShareInfo.getShareCode());
            stockMaxInfo.setType(type);
            Object historyResult = standardService.searchList(stockMaxInfo);
            List<StockMaxInfo> maxInfoList;
            if (!(historyResult instanceof List)){
                maxInfoList = new ArrayList<>();
            }else{
                maxInfoList = (ArrayList<StockMaxInfo>)historyResult;
            }

            log.info(RX_LOG_MODE.DEFAULT.getFormat("最值列表处理前"));
            List<RxBaseData> stockShareInfoList = (List<RxBaseData>)inputMode.handle(maxInfoList);

            if (EmptyChecker.isEmpty(stockShareInfoList)){
                log.info(RX_LOG_MODE.DEFAULT.getFormat("无数据"));
                return;
            }
            log.info(RX_LOG_MODE.DEFAULT.getFormat("批量保存"));
            RxBaseData condition = RxBaseData.create(StockMaxInfo.class, HANDLER_TYPE.SINGLE_BATCH_UPDATE);
            condition.setDataList(stockShareInfoList);
            standardService.batchSave(condition);
        } catch (IllegalAccessException|InstantiationException| RxBaseException e) {
            log.error("error：dealOneShareHistory");
            log.error(RX_LOG_MODE.DEFAULT.getFormat("股票代码【{}】,股票名称【{}】"),"股票信息",stockShareInfo.getShareCode(),stockShareInfo.getShareName());
        }
    }

    private String judgeDirect(List<StockHistoryInfo> historyFromDb,int start,int dayCount,int count){

        int size = historyFromDb.size();
        int i = start;
        if (size < count + start){
            return DIRECT_FLG.UNKNOWN.getCode();
        }
        BigDecimal oneAvg = getAvgByDayCount(historyFromDb.get(i),dayCount);
        BigDecimal first = oneAvg;
        int newFlg = 0;
        int lt = 0;
        int gt = 0;
        for(;i + 1 < count+ start;i++){
            StockHistoryInfo historyInfo = historyFromDb.get(i + 1);
            BigDecimal twoAvg = getAvgByDayCount(historyInfo,dayCount);
            // twoAvg是否比one 小 为UP
            boolean samllerZero = RxUtil.Amount.smaller(twoAvg,oneAvg);
            if (samllerZero){
                gt++;
            }
            if (!samllerZero){
                lt++;
            }
            oneAvg = twoAvg;
        }

        if(dayCount == 5){
            if(gt > lt){
                return DIRECT_FLG.UP.getCode();
            }
            if (lt > gt){
                return DIRECT_FLG.DOWN.getCode();
            }
        }

        StockHistoryInfo historyInfo = historyFromDb.get(count + start - 1);
        BigDecimal last = getAvgByDayCount(historyInfo,dayCount);

        // twoAvg是否比one 小 为UP
        boolean samllerZero = RxUtil.Amount.smaller(last,first);

        if(samllerZero && gt > lt){
            return DIRECT_FLG.UP.getCode();
        }
        if (!samllerZero && lt > gt){
            return DIRECT_FLG.DOWN.getCode();
        }
        return DIRECT_FLG.UNKNOWN.getCode();

    }

    /**
     * 标记上穿21日线
     */
    private void assignUpDoneFlg(StockHistoryInfo stockHistoryInfo,StockHistoryInfo next){
        if (RxUtil.Amount.smallerOr(next.getFiveAvg(),next.getTwentyOneAvg())){
            if (RxUtil.Amount.biggerOr(stockHistoryInfo.getFiveAvg(),stockHistoryInfo.getTwentyOneAvg())){
                stockHistoryInfo.setStatus(RX_STATUS.FORBIDDEN.getCode());
            }
        }else {
            if (RxUtil.Amount.smallerOr(stockHistoryInfo.getFiveAvg(),stockHistoryInfo.getTwentyOneAvg())){
                stockHistoryInfo.setStatus(RX_STATUS.LIMIT.getCode());
            }
        }
    }

    /**
     * 购买关注点
     * @param stockHistoryInfo
     */
    private void assignBuyFlg(StockHistoryInfo stockHistoryInfo){
        if (!DIRECT_FLG.UP.getCode().equalsIgnoreCase(stockHistoryInfo.getFiveDirect())){
           return;
        }
        // 5日均线向上。标记关注
        stockHistoryInfo.setOpFlg(DIRECT_FLG.FLOW.getCode());
        if (RxUtil.Amount.smaller(stockHistoryInfo.getFiveAvg(),stockHistoryInfo.getTwentyOneAvg()) ||
            RxUtil.Amount.smallerOr(stockHistoryInfo.getThirteenAvg(),stockHistoryInfo.getTwentyOneAvg())){
            // 5日均线在21日均线下方
            // 13 日均线在21均线下方
            //log.info("5日均线在21日均线下方");
            return;
        }

        if (!DIRECT_FLG.UP.getCode().equalsIgnoreCase(stockHistoryInfo.getTwentyOneDirect())){
            // 21日均线不向上
            //log.info("21日均线不向上");
            return;
        }
//        if (!DIRECT_FLG.UP.getCode().equalsIgnoreCase(stockHistoryInfo.getThirteenDirect())){
//            log.info("13日均线不向上");
//            return;
//        }
        // 强烈关注
        stockHistoryInfo.setOpFlg(DIRECT_FLG.KEEP.getCode());
        if (!DIRECT_FLG.YES.getCode().equalsIgnoreCase(stockHistoryInfo.getFiftyCompare())) {
            // 量比不足
            return;
        }
        stockHistoryInfo.setOpFlg(DIRECT_FLG.BUY.getCode());
    }
    private void assignSellFlg(StockHistoryInfo stockHistoryInfo,StockHistoryInfo next){
        // 跌破5日均线
        if (RxUtil.Amount.smaller(stockHistoryInfo.getClosePrice(),stockHistoryInfo.getFiveAvg()) &&
                RxUtil.Amount.biggerOr(next.getClosePrice(),next.getFiveAvg())){
            stockHistoryInfo.setOpFlg(DIRECT_FLG.CARE.getCode());

            if(DIRECT_FLG.DOWN.getCode().equalsIgnoreCase(stockHistoryInfo.getFiveDirect())){
                stockHistoryInfo.setOpFlg(DIRECT_FLG.REDUCE.getCode());
            }
            if(DIRECT_FLG.DOWN.getCode().equalsIgnoreCase(stockHistoryInfo.getThirteenDirect())){
                stockHistoryInfo.setOpFlg(DIRECT_FLG.CUTDOWN.getCode());
            }
        }

        if (RxUtil.Amount.smaller(stockHistoryInfo.getFiveAvg(),stockHistoryInfo.getTwentyOneAvg()) &&
                RxUtil.Amount.biggerOr(next.getFiveAvg(),next.getTwentyOneAvg())){
            if(DIRECT_FLG.DOWN.getCode().equalsIgnoreCase(stockHistoryInfo.getFiveDirect())){
                stockHistoryInfo.setOpFlg(DIRECT_FLG.SELL.getCode());
            }
        }
    }

    /**
     * 计算方差
     * @param stockHistoryInfo
     */
    private void assignBuyDiff(List<StockHistoryInfo> historyFromDb,StockHistoryInfo stockHistoryInfo,int i,int size,int count){
        if(!DIRECT_FLG.BUY.getCode().equalsIgnoreCase(stockHistoryInfo.getOpFlg())){
           return;
        }
        count += 1;
        // 买点计算方差及差价
        if(size <= i + count){
           return;
        }

        int start = i;
        BigDecimal diff = BigDecimal.ZERO;
        StockHistoryInfo tmp = stockHistoryInfo;
        for(;start < i + count;start++){
            tmp = historyFromDb.get(start);
            if (RxUtil.Amount.smaller(tmp.getClosePrice(),tmp.getFiveAvg())){
                diff = RxUtil.Amount.add(diff,RxUtil.Amount.subtract(tmp.getFiveAvg(),tmp.getClosePrice()));
            }
        }
        diff = RxUtil.Amount.divideRound(diff,count,5);
        diff = RxUtil.Amount.divideRound(diff,stockHistoryInfo.getClosePrice(),4);
        stockHistoryInfo.setDiffPrice(diff);
        stockHistoryInfo.setHighPrice(RxUtil.Amount.divideRound(
                RxUtil.Amount.subtract(stockHistoryInfo.getClosePrice(),tmp.getClosePrice()),
                stockHistoryInfo.getClosePrice(),3));
    }

    boolean judgeDiffPrice(StockHistoryInfo stockHistoryInfo,StockShareInfo stockShareInfo){
        if (EmptyChecker.isEmpty(stockHistoryInfo.getDiffPrice())){
            return false;
        }
        if (EmptyChecker.isEmpty(stockHistoryInfo.getHighPrice())){
            return false;
        }
        BigDecimal diffParam = BigDecimal.ZERO;
        if(EmptyChecker.notEmpty(stockShareInfo.getDiffParam())){
            diffParam = stockShareInfo.getDiffParam();
        }

        if(RxUtil.Amount.smaller(diffParam,stockHistoryInfo.getDiffPrice())){
            return false;
        }

        BigDecimal highParam = new BigDecimal(1);
        if (EmptyChecker.notEmpty(stockShareInfo.getHighParam())){
            highParam = stockShareInfo.getHighParam();
        }

        if (RxUtil.Amount.smaller(highParam,stockHistoryInfo.getHighPrice())){
            return false;
        }
        return  true;
    }

    void assignDirectFlg(List<StockHistoryInfo> historyFromDb,int i,int size,StockShareInfo stockShareInfo){
        StockHistoryInfo stockHistoryInfo = historyFromDb.get(i);
        StockHistoryInfo next = historyFromDb.get(i + 1);


        stockHistoryInfo.setFiveDirect(judgeDirect(historyFromDb,i,5,stockShareInfo.getFiveParam()));
        stockHistoryInfo.setThirteenDirect(judgeDirect(historyFromDb,i,13,stockShareInfo.getThirteenParam()));
        stockHistoryInfo.setTwentyOneDirect(judgeDirect(historyFromDb,i,21,stockShareInfo.getTwentyParam()));
        if (RxUtil.Amount.bigger(stockHistoryInfo.getTurnOver(),stockHistoryInfo.getFiftyAvg())){
            stockHistoryInfo.setFiftyCompare(DIRECT_FLG.YES.getCode());
        }else{
            stockHistoryInfo.setFiftyCompare(DIRECT_FLG.NO.getCode());
        }
        stockHistoryInfo.setStatus(RX_STATUS.NORMAL.getCode());
        // 5 日均线上穿 21 日
        assignUpDoneFlg(stockHistoryInfo,next);

        if (RxUtil.Amount.bigger(stockHistoryInfo.getClosePrice(),stockHistoryInfo.getFiveAvg())){
            assignBuyFlg(stockHistoryInfo);
            assignBuyDiff(historyFromDb,stockHistoryInfo,i,size,stockShareInfo.getThirteenParam());
        }else{
            assignSellFlg(stockHistoryInfo,next);
        }
    }
    List<RxBaseData> assignBuySellFlg(List<StockHistoryInfo> historyFromDb,int index,int size,StockShareInfo stockShareInfo){
        List<RxBaseData> stockShareInfoList = new ArrayList<>();
        boolean fiveUpToTwenty = false;
        boolean yesBuy = false;
        BigDecimal buyPrice = BigDecimal.ZERO;
        BigDecimal highPrice = BigDecimal.ZERO;
        boolean upDone = false;
        for(index =  size - 2;index >=0 ;index--){
            StockHistoryInfo stockHistoryInfo = historyFromDb.get(index);
            if (RX_STATUS.FORBIDDEN.getCode().equalsIgnoreCase(stockHistoryInfo.getStatus())){
                upDone = true;
            }else if (RX_STATUS.LIMIT.getCode().equalsIgnoreCase(stockHistoryInfo.getStatus())){
                upDone = false;
            }
            // 5日线上传21日线
            if(!yesBuy && upDone){
                fiveUpToTwenty = true;
            }

            if (RxUtil.Amount.smaller(stockHistoryInfo.getFiveAvg(),stockHistoryInfo.getTwentyOneAvg())){
                // 5日线穿破21日线
                fiveUpToTwenty = false;
            }

            if (fiveUpToTwenty){
                if(DIRECT_FLG.BUY.getCode().equalsIgnoreCase(stockHistoryInfo.getOpFlg())
                        &&judgeDiffPrice(stockHistoryInfo,stockShareInfo)){
                    // 买点
                    fiveUpToTwenty = false;
                    yesBuy = true;
                    buyPrice = stockHistoryInfo.getClosePrice();
                    stockHistoryInfo.setOpFlg(DIRECT_FLG.B.getCode());
                }
            }
            if(yesBuy){
                // 有买点才有卖点
                if(DIRECT_FLG.SELL.getCode().equalsIgnoreCase(stockHistoryInfo.getOpFlg()) ){
                    // 真卖点
                    yesBuy = false;
                    stockHistoryInfo.setDiffPrice(RxUtil.Amount.divideRound(RxUtil.Amount.subtract(stockHistoryInfo.getClosePrice(),buyPrice)
                            ,stockHistoryInfo.getClosePrice(),3));
                    stockHistoryInfo.setHighPrice(RxUtil.Amount.divideRound(highPrice,stockHistoryInfo.getClosePrice(),3));
                    stockHistoryInfo.setOpFlg(DIRECT_FLG.S.getCode());
                }
                if(DIRECT_FLG.CUTDOWN.getCode().equalsIgnoreCase(stockHistoryInfo.getOpFlg())){
                    stockHistoryInfo.setDiffPrice(RxUtil.Amount.divideRound(RxUtil.Amount.subtract(stockHistoryInfo.getClosePrice(),buyPrice),
                            stockHistoryInfo.getClosePrice(),3));
                    stockHistoryInfo.setHighPrice(RxUtil.Amount.divideRound(highPrice,stockHistoryInfo.getClosePrice(),3));
                }
                BigDecimal diffTmp = RxUtil.Amount.subtract(stockHistoryInfo.getClosePrice(),buyPrice);
                if (RxUtil.Amount.smaller(diffTmp,highPrice)){
                    highPrice = diffTmp;
                }
            }else{
                highPrice = BigDecimal.ZERO;
                if(DIRECT_FLG.SELL.getCode().equalsIgnoreCase(stockHistoryInfo.getOpFlg())
                        || DIRECT_FLG.CARE.getCode().equalsIgnoreCase(stockHistoryInfo.getOpFlg())
                        || DIRECT_FLG.CUTDOWN.getCode().equalsIgnoreCase(stockHistoryInfo.getOpFlg())
                        || DIRECT_FLG.REDUCE.getCode().equalsIgnoreCase(stockHistoryInfo.getOpFlg())){
                    // 假买点
                    stockHistoryInfo.setOpFlg(null);
                }
            }
            //if(upd){
            stockShareInfoList.add(stockHistoryInfo);
            //}
        }
        return stockShareInfoList;
    }
    /**
     * 标记趋势。买点。卖点
     */
    private void updateShareFlg(){
        dealOneShare(info->{
            StockShareInfo stockShareInfo = (StockShareInfo)info;
            dealOneShareHistory(stockShareInfo,stock->{
                List<StockHistoryInfo> historyFromDb = (List<StockHistoryInfo>)stock;

                int i = 0;
                int size = historyFromDb.size();
                if (size < 10){
                    return new ArrayList<>();
                }
                for(;i < size - 1;i++){
                    assignDirectFlg(historyFromDb,i,size,stockShareInfo);
                }

                return assignBuySellFlg(historyFromDb,i,size,stockShareInfo);
            });
        });
    }

    private List getSzShareHistoryJson(String date){
        //String requestUrl = "http://jk791.com/stock/history/queryDayStockHistoryInfo";
        String requestUrl = "http://www.szse.cn/api/report/ShowReport/data";

        Map<String, String> requestUrlParam = new HashMap<>();
        requestUrlParam.put("SHOWTYPE", "JSON");
        requestUrlParam.put("CATALOGID", "1815_stock");
        requestUrlParam.put("TABKEY", "tab1");
        requestUrlParam.put("PAGENO", "1");
        requestUrlParam.put("tab1PAGESIZE", "5000");
        requestUrlParam.put("TABKEY", "tab1");
        requestUrlParam.put("txtBeginDate", date);
        requestUrlParam.put("txtEndDate", date);
        requestUrlParam.put("txtSite","all");
        requestUrlParam.put("random","0.568356241157921");

        String json = HttpClientUtil.doGet(requestUrl, requestUrlParam);
        //String json = "[{\"dm\":\"000001\",\"jys\":\"sz\",\"mz\":\"平安银行\"},{\"dm\":\"000002\",\"jys\":\"sz\",\"mz\":\"万 科Ａ\"},{\"dm\":\"000004\",\"jys\":\"sz\",\"mz\":\"国华网安\"},{\"dm\":\"000005\",\"jys\":\"sz\",\"mz\":\"ST星源\"},{\"dm\":\"000006\",\"jys\":\"sz\",\"mz\":\"深振业Ａ\"}]";
        log.info("sh json:" + json);

        List<NetShareInfoFromsz> list = JSONArray.parseArray(json, NetShareInfoFromsz.class);
        if(EmptyChecker.isEmpty(list)){
            return Collections.EMPTY_LIST;
        }

        return list.get(0).getData();

    }

    private  List<StockHistoryInfo> getHistoryByDate(String dateString){
        List<StockHistoryInfo> stockHistoryInfoList = null;
        SimpleDateFormat dateFormat = new SimpleDateFormat(RxBaseConstant.DATE_FORMAT_DATETIME);

        try {
            stockHistoryInfoList = getHistoryList(dateFormat.parse(dateString + " 12:00:00"),null,false);
        } catch (ParseException e) {

        }
        if (EmptyChecker.isEmpty(stockHistoryInfoList)){
            return Collections.EMPTY_LIST;
        }
        int size = stockHistoryInfoList.size();
        if (size < MON_TRN_DAY){
            return Collections.EMPTY_LIST;
        }
        return stockHistoryInfoList;
    }

    private BigDecimal changeAmount(String amount){
        if (EmptyChecker.isEmpty(amount)){
            return BigDecimal.ZERO;
        }
        return new BigDecimal(amount.replace(",",""));
    }
    private String removeComma(String amount){
        if (EmptyChecker.isEmpty(amount)){
            return "0";
        }
        return amount.replace(",","");
    }


    public void  updateSzHistory(){
        // 获取所有股票信息
        List<StockShareInfo> stockShareInfoList = new ArrayList<>();
        dealOneShare(info-> stockShareInfoList.add((StockShareInfo) info));
        Map<String,List<StockShareInfo>> mapShare = stockShareInfoList.stream()
                .collect(Collectors.groupingBy(StockShareInfo::getShareCode));
        // 日期
        Date now  = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(RxBaseConstant.DATE_FORMAT_DATEONLY);
        String nowString = formatter.format(now);
        log.info("今天："+nowString);
        int preDate = -50;

        Calendar calendar=Calendar.getInstance();

        calendar.add(Calendar.DATE,preDate);

        for(;preDate < -49;preDate++){

            Date date = calendar.getTime();

            if ((calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY)   ||
                    (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY)) {
                calendar.add(Calendar.DATE,+1);
                continue;
            }

            calendar.add(Calendar.DATE,+1);
            String dateString = formatter.format(date);
            log.info("日期："+dateString);
            List<NetShareInfoFromsz.MetaInfo> metaInfos = getSzShareHistoryJson(dateString);

            if (EmptyChecker.isEmpty(metaInfos)){
                continue;
            }
            // 当天的所有股票

            List<StockHistoryInfo> stockHistoryInfoList = getHistoryByDate(dateString);
            if (EmptyChecker.isEmpty(stockHistoryInfoList)){
                // 新增
            }else {
                Map<String,List<StockHistoryInfo>> map = stockHistoryInfoList.stream()
                        .collect(Collectors.groupingBy(StockHistoryInfo::getShareCode));
                // 更改
                for(int index = 0;index < metaInfos.size();index++){
                    NetShareInfoFromsz.MetaInfo metaInfo = metaInfos.get(index);
                    List<StockHistoryInfo> historyInfoList = map.get(metaInfo.getZqdm());

                    List<StockShareInfo> stockShareInfos = mapShare.get(metaInfo.getZqdm());

                    if (EmptyChecker.notEmpty(historyInfoList)){
                        historyInfoList.get(0).setClosePrice(changeAmount(metaInfo.getSs()));
                        historyInfoList.get(0).setOpenPrice(changeAmount(metaInfo.getKs()));
                        historyInfoList.get(0).setHighestPrice(changeAmount(metaInfo.getZg()));
                        historyInfoList.get(0).setLowestPrice(changeAmount(metaInfo.getZd()));
                        historyInfoList.get(0).setTurnOver(changeAmount(metaInfo.getCjgs()));
                        historyInfoList.get(0).setTurnAmount(changeAmount(metaInfo.getCjje()));
                        historyInfoList.get(0).setChangeRate(changeAmount(metaInfo.getSdf()));
                        BigDecimal changeRate =RxUtil.Amount.divideRound(changeAmount(metaInfo.getCjgs()).multiply(new BigDecimal(100)),stockShareInfos.get(0).getNegotiableCapital());
                        log.info("hange->" + changeRate + ":" + historyInfoList.get(0).getSwitchRate());
                    }

                }
            }

        }

    }

    public void updateShHistory(){

    }

    private  List<NetHiShareInfo> getHiNetList( StockShareInfo stockShareInfo,int flg){
        if (0 == flg){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {

            }
            String json = getShareHistoryJson(stockShareInfo.getShareCode());
            return JSONArray.parseArray(json, NetHiShareInfo.class);
        }

        String json = getShareHistoryJsonFromDF(stockShareInfo,false);
        NetShareInfoFromDf netShareInfoFromDf = JSONObject.parseObject(json,NetShareInfoFromDf.class);
        List<NetHiShareInfo> resultList = new ArrayList<>();
        for (String kline : netShareInfoFromDf.getData().getKlines()) {
            NetHiShareInfo netHiShareInfo = NetHiShareInfo.createStockShareInfo(kline);
            resultList.add(netHiShareInfo);
        }
        return resultList;
    }

    private  List<NetLatestShareInfo> getLastNetList( StockShareInfo stockShareInfo,int flg){
        if (0 == flg){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {

            }
            String json = getShareLatestJson(stockShareInfo.getShareCode());
            return JSONArray.parseArray(json, NetLatestShareInfo.class);
        }

        String json = getShareHistoryJsonFromDF(stockShareInfo,true);
        NetShareInfoFromDf netShareInfoFromDf = JSONObject.parseObject(json,NetShareInfoFromDf.class);
        List<NetLatestShareInfo> resultList = new ArrayList<>();
        for (String kline : netShareInfoFromDf.getData().getKlines()) {
            NetLatestShareInfo netHiShareInfo = NetLatestShareInfo.createStockShareInfo(kline);
            resultList.add(netHiShareInfo);
        }
        return resultList;
    }

    public void updateHistory(){
        dealOneShare(info-> {

            StockShareInfo stockShareInfo = (StockShareInfo)info;
            List<NetHiShareInfo> list = getHiNetList(stockShareInfo,1);
            if(EmptyChecker.isEmpty(list)){
                return;
            }
            log.info(RX_LOG_MODE.DEFAULT.getFormat("获取列表"));
            dealOneShareHistory(stockShareInfo,stock-> {
                List<StockHistoryInfo> historyFromDb = (List<StockHistoryInfo>) stock;

                Map<String,StockHistoryInfo> map = null;
                boolean dbHave = false;
                if (EmptyChecker.notEmpty(historyFromDb)){
                    map= historyFromDb.stream().collect(Collectors.toMap(o->{
                        return o.getShareCode() + o.getTradeTime().toString();
                    },o->o));
                    dbHave = true;
                }


                log.info(RX_LOG_MODE.DEFAULT.getFormat("判断是否为更新"));
                List<StockHistoryInfo> stockShareInfoList = new ArrayList<>();
                for (NetHiShareInfo netShareInfo : list) {

                    StockHistoryInfo infoFromNet = netShareInfo.createStockShareInfo();
                    infoFromNet.setShareCode(stockShareInfo.getShareCode());
                    infoFromNet.setStatus(RX_STATUS.NORMAL.getCode());

                    if (dbHave){
                        StockHistoryInfo fromDb = map.get(infoFromNet.getShareCode() + infoFromNet.getTradeTime().toString());
                        if(EmptyChecker.notEmpty(fromDb)){
                            infoFromNet.setBid(fromDb.getBid());
                            infoFromNet.setVer(fromDb.getVer());
                        }
                    }

                    stockShareInfoList.add(infoFromNet);
                }

                // 倒叙
                stockShareInfoList = stockShareInfoList.stream().sorted(Comparator.comparing(StockHistoryInfo::getTradeTime).reversed()).collect(Collectors.toList());
                log.info(RX_LOG_MODE.DEFAULT.getFormat("倒叙"));
                List<StockHistoryInfo> afterAvgList = new ArrayList<>();

                log.info(RX_LOG_MODE.DEFAULT.getFormat("均值处理"));
                assignAvg(stockShareInfoList,stockShareInfo,afterAvgList);
                // 均值

                int i = 0;
                int size = afterAvgList.size();
                if (size < 13){
                    return new ArrayList<>();
                }

                log.info(RX_LOG_MODE.DEFAULT.getFormat("趋势处理"));
                for(;i < size - 1;i++){
                    assignDirectFlg(afterAvgList,i,size,stockShareInfo);
                }

                log.info(RX_LOG_MODE.DEFAULT.getFormat("买点卖点处理"));
                return assignBuySellFlg(afterAvgList,i,size,stockShareInfo);
            });

        });
        log.info(RX_LOG_MODE.DEFAULT.getFormat("完成"));
    }
    /**
     * 更新最新数据
     */
    public void updateLatest(){
        dealOneShare(info-> {

            StockShareInfo stockShareInfo = (StockShareInfo) info;

            List<NetLatestShareInfo> list = getLastNetList(stockShareInfo,1);
            if(EmptyChecker.isEmpty(list)){
                return;
            }

            //JSONObject jsonObject=JSONObject.parseObject(json);
            //NetLatestShareInfo netLatestShareInfo = jsonObject.toJavaObject(NetLatestShareInfo.class);
            NetLatestShareInfo netLatestShareInfo = list.get(0);
            StockHistoryInfo stockHistoryInfo = netLatestShareInfo.createStockShareInfo(1);
            stockHistoryInfo.setShareCode(stockShareInfo.getShareCode());
            dealOneShareHistory(stockShareInfo,stock->{
                List<StockHistoryInfo> historyFromDb = (List<StockHistoryInfo>)stock;
                StockHistoryInfo first = (StockHistoryInfo)RxUtil.ListUtil.getFirst(historyFromDb);
                StockHistoryInfo tmpInfo = stockHistoryInfo;
                if (first.getTradeTime().toString().equalsIgnoreCase(stockHistoryInfo.getTradeTime().toString())){
                    first.copyValue(stockHistoryInfo);
                    tmpInfo = first;
                }else {
                    historyFromDb.add(0,tmpInfo);
                }


                BigDecimal fiveAvg = initAvgPrice(historyFromDb,5);
                BigDecimal thirTeenAvg = initAvgPrice(historyFromDb,13);
                BigDecimal twentyOneAvg = initAvgPrice(historyFromDb,21);
                BigDecimal fiftyAvg = initAvgVolunm(historyFromDb,50);
                BigDecimal avgSwitch = initAvgSwitchRate(historyFromDb,stockShareInfo.getThirteenParam());


                tmpInfo.setFiveAvg(fiveAvg);
                tmpInfo.setThirteenAvg(thirTeenAvg);
                tmpInfo.setTwentyOneAvg(twentyOneAvg);
                tmpInfo.setFiftyAvg(fiftyAvg);
                tmpInfo.setAvgSwitch(avgSwitch);

                tmpInfo.setDiffSwitch(RxUtil.Amount.subtract(tmpInfo.getSwitchRate(),historyFromDb.get(0).getSwitchRate()));


                int size = historyFromDb.size();
                assignDirectFlg(historyFromDb,0,size,stockShareInfo);

                // 从最近三年的趋势
                int index = 800;
                if (size <= index){
                    index = size - 1;
                }
                assignBuySellFlg(historyFromDb,index,size,stockShareInfo);
                List<RxBaseData> stockShareInfoList = new ArrayList<>();
                stockShareInfoList.add(tmpInfo);

                return stockShareInfoList;
            });
        });
    }
    /**
     * 从网络获取股票数据
      */
    public Object runData(){

        //updateShareInfo();
        //updateShareTradeHistory();
        updateShareAvg();
        updateShareFlg();
        //updateLatest();
        return Integer.valueOf(0);
    }
    public Object runForAvg(){
        updateShareAvg();
        return Integer.valueOf(0);
    }

    public Object runForFlg(){
        updateShareFlg();
        return Integer.valueOf(0);
    }

    public Object runFlgNoSave(){
        updateShareFlg();
        return Integer.valueOf(0);
    }

    public Object getAllShare(){
        updateShareInfo();
        return Integer.valueOf(0);
    }

    public Object getAllHistory(){
        // 异步执行
        asyncTask.runAllHistory();
        return Integer.valueOf(0);
    }

    public Object getAllLatest(){
        asyncTask.runLatest();
        return Integer.valueOf(0);
    }

    public Object getSzHistory(){
        asyncTask.getSzHistory();
        return Integer.valueOf(0);
    }

    public Object getShHistory(){
        asyncTask.getShHistory();
        return Integer.valueOf(0);
    }


    List<MaxLocationInfo> findMax(int index,int count,ReturnInputMode returnInputMode){
        MaxLocationInfo maxLocationInfo = (MaxLocationInfo)returnInputMode.handle(index);
        MaxLocationInfo min = maxLocationInfo;
        min.setMaxFlg(MAX_FLG.MIN.getCode());
        MaxLocationInfo max = min.clone();
        max.setMaxFlg(MAX_FLG.MAX.getCode());
        index++;
        int start = index;
        for (;index < start + count;index++) {
            maxLocationInfo = (MaxLocationInfo)returnInputMode.handle(index);
            BigDecimal close = maxLocationInfo.getAmount();

            if (RxUtil.Amount.bigger(min.getAmount(),close)){
                min.setIndex(index);
                min.setAmount(close);
                min.setTradeTime(maxLocationInfo.getTradeTime());
            }
            if (RxUtil.Amount.smaller(max.getAmount(),close)){
                max.setIndex(index);
                max.setAmount(close);
                max.setTradeTime(maxLocationInfo.getTradeTime());
            }
        }

        List<MaxLocationInfo> resultList = new ArrayList<>();
        if (min.getIndex() < max.getIndex()){
            resultList.add(min);
            resultList.add(max);
        }else {
            resultList.add(max);
            resultList.add(min);
        }
        return resultList;
    }

    /**
     * 找一个月内落差比较大的起伏
     * @return
     */
    List<MaxLocationInfo> findDiffDrop(MaxLocationInfo first,MaxLocationInfo second,BigDecimal rate,ReturnInputMode returnInputMode){
        BigDecimal rateAmount = BigDecimal.ZERO;
        if (MAX_FLG.MAX.getCode().equalsIgnoreCase(first.getMaxFlg())){
            rateAmount = RxUtil.Amount.subtract(first.getAmount(),RxUtil.Amount.multiply(first.getAmount(),rate));
            if (RxUtil.Amount.biggerOr(second.getAmount(),rateAmount)){
                return new ArrayList<>();
            }
        }else {
            rateAmount = RxUtil.Amount.add(first.getAmount(),RxUtil.Amount.multiply(first.getAmount(),rate));
            if (RxUtil.Amount.smallerOr(second.getAmount(),rateAmount)){
                return new ArrayList<>();
            }
        }

        // 定点
        MaxLocationInfo oneDot = first;
        MaxLocationInfo twoDot = first;
        MaxLocationInfo tmp = first;
        List<Integer> dotList = new ArrayList<>();
        int index = first.getIndex() + 1;
        boolean haveOneDot = false;
        boolean hasTweDot = false;
        List<MaxLocationInfo> resultList = new ArrayList<>();
        for (;index < second.getIndex() - 1;index++) {
            MaxLocationInfo maxLocationInfo = (MaxLocationInfo)returnInputMode.handle(index);
            BigDecimal closePrice = maxLocationInfo.getAmount();
            if (MAX_FLG.MAX.getCode().equalsIgnoreCase(first.getMaxFlg())){

                if (haveOneDot){

                    if (!hasTweDot){
                        rateAmount = RxUtil.Amount.add(oneDot.getAmount(),RxUtil.Amount.multiply(oneDot.getAmount(),rate));
                        if (RxUtil.Amount.bigger(closePrice,rateAmount)){
                            twoDot = tmp;
                            hasTweDot = true;
                            resultList.add(oneDot);
                        }
                    }else {
                        if (RxUtil.Amount.bigger(closePrice,twoDot.getAmount())){
                            twoDot = tmp;
                        }

                        rateAmount = RxUtil.Amount.subtract(twoDot.getAmount(),RxUtil.Amount.multiply(twoDot.getAmount(),rate));

                        // 处于第二个点下降过程中但 还未跌倒第一个点
                        if (RxUtil.Amount.smaller(closePrice,rateAmount) &&
                                RxUtil.Amount.bigger(closePrice,oneDot.getAmount())){
                            twoDot.setMaxFlg(MAX_FLG.MAX.getCode());
                            resultList.add(twoDot);
                            haveOneDot = false;
                            hasTweDot = false;
                            continue;
                        }
                    }


                    if (RxUtil.Amount.smaller(closePrice,oneDot.getAmount())){
                        // 比第一个点低
                        if (hasTweDot){
                            twoDot.setMaxFlg(MAX_FLG.MAX.getCode());
                            resultList.add(twoDot);
                        }
                        haveOneDot = false;
                        hasTweDot = false;
                    }
                }else {
                    if (RxUtil.Amount.bigger(closePrice,tmp.getAmount())){
                        oneDot = tmp;
                        oneDot.setMaxFlg(MAX_FLG.MIN.getCode());
                        haveOneDot = true;
                    }
                }

            } else {
                if (haveOneDot){

                    if (!hasTweDot){
                        rateAmount = RxUtil.Amount.subtract(oneDot.getAmount(),RxUtil.Amount.multiply(oneDot.getAmount(),rate));
                        if (RxUtil.Amount.smaller(closePrice,rateAmount)){
                            twoDot = tmp;
                            hasTweDot = true;
                            resultList.add(oneDot);
                        }
                    }else {
                        if (RxUtil.Amount.smaller(closePrice,twoDot.getAmount())){
                            twoDot = tmp;
                        }

                        rateAmount = RxUtil.Amount.add(twoDot.getAmount(),RxUtil.Amount.multiply(twoDot.getAmount(),rate));

                        // 处于第二个点上升过程中但 还未涨到第一个点
                        if (RxUtil.Amount.bigger(closePrice,rateAmount) &&
                                RxUtil.Amount.smaller(closePrice,oneDot.getAmount())){
                            twoDot.setMaxFlg(MAX_FLG.MIN.getCode());
                            resultList.add(twoDot);
                            haveOneDot = false;
                            hasTweDot = false;
                            continue;
                        }
                    }


                    if (RxUtil.Amount.bigger(closePrice,oneDot.getAmount())){
                        // 比第一个点高
                        if (hasTweDot){
                            twoDot.setMaxFlg(MAX_FLG.MIN.getCode());
                            resultList.add(twoDot);
                        }
                        haveOneDot = false;
                        hasTweDot = false;
                    }
                }else {
                    if (RxUtil.Amount.smaller(closePrice,tmp.getAmount())){
                        oneDot = tmp;
                        oneDot.setMaxFlg(MAX_FLG.MAX.getCode());
                        haveOneDot = true;
                    }
                }
            }

            tmp = maxLocationInfo;
        }

        return resultList;
    }

    private void setResultByMaxLocation(List<MaxLocationInfo> maxLocationInfoList,List<RxBaseData> resultList,String shareCode){
        if (EmptyChecker.isEmpty(maxLocationInfoList)){
            return;
        }
        if (null == resultList){
            return;
        }

        for (MaxLocationInfo maxLocationInfo : maxLocationInfoList) {
            resultList.add(StockMaxInfo.createByLocation(maxLocationInfo,shareCode));
        }
    }

    private void setLastMax(MaxLocationInfo max,MaxLocationInfo min,MaxLocationInfo last,List<MaxLocationInfo> maxLocationInfoList){
        if (EmptyChecker.isEmpty(maxLocationInfoList)){
            return;
        }


        max.setMaxFlg(MAX_FLG.MAX.getCode());
        min.setMaxFlg(MAX_FLG.MIN.getCode());
        if (maxLocationInfoList.size() == 1){
            if (MAX_FLG.MAX.getCode().equalsIgnoreCase(maxLocationInfoList.get(0).getMaxFlg())){
                max.assign(maxLocationInfoList.get(0));
            }else {
                min.assign(maxLocationInfoList.get(0));
            }
            last.assign(maxLocationInfoList.get(0));
            return;
        }

        int oneIndex = maxLocationInfoList.size() - 2;
        int twoIndex = maxLocationInfoList.size() - 1;
        if (MAX_FLG.MAX.getCode().equalsIgnoreCase(maxLocationInfoList.get(oneIndex).getMaxFlg())){
            min.assign(maxLocationInfoList.get(twoIndex));
            max.assign(maxLocationInfoList.get(oneIndex));
        }else {
            max.assign(maxLocationInfoList.get(twoIndex));
            min.assign(maxLocationInfoList.get(oneIndex));
        }

        last.assign(maxLocationInfoList.get(twoIndex));
    }

    private void setDiffDrop(MaxLocationInfo first,MaxLocationInfo second,MaxParamInfo maxParamInfo ){
        List<MaxLocationInfo> dropList = findDiffDrop(first,second,new BigDecimal(minChangeRate),
                (oIdx)->{
                    StockHistoryInfo shInfo = maxParamInfo.getStockHistoryInfoList().get((int)oIdx);
                    return MaxLocationInfo.create(shInfo,(int)oIdx);
                });
        setResultByMaxLocation(dropList,maxParamInfo.getResultList(),maxParamInfo.getStockShareInfo().getShareCode());
        setLastMax(maxParamInfo.getMaxLast(),maxParamInfo.getMinLast(),maxParamInfo.getLastMax(),dropList);
    }

    private void dealIsUpdateForMax(List<StockMaxInfo> mapListFormDb,List<RxBaseData> resultList,String type){
        Map<String,StockMaxInfo> map = mapListFormDb.stream().collect(Collectors.toMap(o->{
            return o.getShareCode() + o.getTradeTime().toString();
        },o->o));
        int i = 0;
        for (;i < resultList.size() - 1;i++){
            StockMaxInfo stockMaxInfo = (StockMaxInfo)resultList.get(i);
            StockMaxInfo next = (StockMaxInfo)resultList.get(i + 1);
            StockMaxInfo stockdb = map.get(stockMaxInfo.getShareCode() + stockMaxInfo.getTradeTime().toString());
            if (EmptyChecker.notEmpty(stockdb)){
                stockMaxInfo.setBid(stockdb.getBid());
                stockMaxInfo.setVer(stockdb.getVer());
            }
            stockMaxInfo.setDiffAmount(RxUtil.Amount.subtract(next.getAmount(),stockMaxInfo.getAmount()));
            stockMaxInfo.setType(type);
            stockMaxInfo.setDiffRate(RxUtil.Amount.divideRound(stockMaxInfo.getDiffAmount(),stockMaxInfo.getAmount(),4));
        }
    }
    private List<RxBaseData> dealMaxWithRate(List<RxBaseData> resultList,Object maxObjects,StockShareInfo stockShareInfo,String type,String rate){
        List<RxBaseData> resultSmallerList = new ArrayList<>();
        List<StockMaxInfo> mapListFormDb = (List<StockMaxInfo> )maxObjects;
        int index = 0;
        int rsize = resultList.size();

        MaxParamInfo maxParamInfo = new MaxParamInfo();
        maxParamInfo.setResultList(resultSmallerList);
        maxParamInfo.setStockShareInfo(stockShareInfo);

        /**
         * 找到一段时间MON_TRN_DAY中的最高点，最低点 即找极值。
         */
        List<MaxLocationInfo> maxTmpList = findMax(index,rsize-1,(oIdx)->{
            StockMaxInfo shInfo = (StockMaxInfo)resultList.get((int)oIdx);
            return MaxLocationInfo.create(shInfo,(int)oIdx);
        });
        MaxLocationInfo first = MaxLocationInfo.create((StockMaxInfo)resultList.get(index),index);
        MaxLocationInfo second = MaxLocationInfo.create((StockMaxInfo)resultList.get(rsize - 1),rsize - 1);

        if (MAX_FLG.MAX.getCode().equalsIgnoreCase(maxTmpList.get(0).getMaxFlg())){
            first.setMaxFlg(MAX_FLG.MIN.getCode());
            second.setMaxFlg(MAX_FLG.MAX.getCode());

        }else {
            first.setMaxFlg(MAX_FLG.MAX.getCode());
            second.setMaxFlg(MAX_FLG.MIN.getCode());
        }


        if(maxTmpList.get(0).getIndex() > 0){

            maxParamInfo.getResultList().add(StockMaxInfo.createByLocation(first,maxParamInfo.getStockShareInfo().getShareCode()));
            List<MaxLocationInfo> dropList = findDiffDrop(first,maxTmpList.get(0),new BigDecimal(rate),
                    (oIdx)->{
                        StockMaxInfo shInfo = (StockMaxInfo)resultList.get((int)oIdx);
                        return MaxLocationInfo.create(shInfo,(int)oIdx);
                    });
            setResultByMaxLocation(dropList,maxParamInfo.getResultList(),maxParamInfo.getStockShareInfo().getShareCode());

        }
        maxParamInfo.getResultList().add(StockMaxInfo.createByLocation(maxTmpList.get(0),maxParamInfo.getStockShareInfo().getShareCode()));

        List<MaxLocationInfo> dropList = findDiffDrop(maxTmpList.get(0),maxTmpList.get(1),new BigDecimal(rate),
                (oIdx)->{
                    StockMaxInfo shInfo = (StockMaxInfo)resultList.get((int)oIdx);
                    return MaxLocationInfo.create(shInfo,(int)oIdx);
                });
        setResultByMaxLocation(dropList,maxParamInfo.getResultList(),maxParamInfo.getStockShareInfo().getShareCode());

        maxParamInfo.getResultList().add(StockMaxInfo.createByLocation(maxTmpList.get(1),maxParamInfo.getStockShareInfo().getShareCode()));

        if (rsize - 1 > maxTmpList.get(1).getIndex()){
            dropList = findDiffDrop(maxTmpList.get(1),second,new BigDecimal(rate),
                    (oIdx)->{
                        StockMaxInfo shInfo = (StockMaxInfo)resultList.get((int)oIdx);
                        return MaxLocationInfo.create(shInfo,(int)oIdx);
                    });
            setResultByMaxLocation(dropList,maxParamInfo.getResultList(),maxParamInfo.getStockShareInfo().getShareCode());

            maxParamInfo.getResultList().add(StockMaxInfo.createByLocation(second,maxParamInfo.getStockShareInfo().getShareCode()));

        }



        dealIsUpdateForMax(mapListFormDb,resultSmallerList,type);
        return resultSmallerList;
    }

    MaxLocationInfo getPeek(List<StockHistoryInfo> stockHistoryInfoList,int start,int end,boolean max){
        MaxLocationInfo peekAmount = MaxLocationInfo.create(stockHistoryInfoList.get(start),start);
        if (max){
            peekAmount.setMaxFlg(MAX_FLG.MAX.getCode());
        }else{
            peekAmount.setMaxFlg(MAX_FLG.MIN.getCode());
        }
        start++;
        for (;start <= end;start++){
            if (max){
                if (RxUtil.Amount.bigger(stockHistoryInfoList.get(start).getClosePrice(),peekAmount.getAmount())){
                    peekAmount = MaxLocationInfo.create(stockHistoryInfoList.get(start),start);
                    peekAmount.setMaxFlg(MAX_FLG.MAX.getCode());
                }
            }else {
                if (RxUtil.Amount.smaller(stockHistoryInfoList.get(start).getClosePrice(),peekAmount.getAmount())){
                    peekAmount = MaxLocationInfo.create(stockHistoryInfoList.get(start),start);
                    peekAmount.setMaxFlg(MAX_FLG.MIN.getCode());
                }
            }
        }
        return peekAmount;
    }


    public void calculateMax(){
        dealOneShare(info-> {
            StockShareInfo stockShareInfo = (StockShareInfo) info;
            List<StockHistoryInfo> stockHistoryInfoList = getHistoryList(null,stockShareInfo.getShareCode(),false);
            if (EmptyChecker.isEmpty(stockHistoryInfoList)){
                return;
            }
            int size = stockHistoryInfoList.size();
            if (size < MON_TRN_DAY){
                return;
            }
            List<RxBaseData> resultList = new ArrayList<>();

            dealOneShareMax(stockShareInfo,MAX_TYPE.N.getCode(),maxObjects->{
                List<StockMaxInfo> mapListFormDb = (List<StockMaxInfo> )maxObjects;

                int index = 0;

                MaxParamInfo maxParamInfo = new MaxParamInfo();
                maxParamInfo.setResultList(resultList);
                maxParamInfo.setStockHistoryInfoList(stockHistoryInfoList);
                maxParamInfo.setStockShareInfo(stockShareInfo);

                for (;index < size-MON_TRN_DAY;) {

                    /**
                     * 找到一段时间MON_TRN_DAY中的最高点，最低点 即找极值。
                     */
                    List<MaxLocationInfo> maxTmpList = findMax(index,MON_TRN_DAY,(oIdx)->{
                        StockHistoryInfo shInfo = maxParamInfo.getStockHistoryInfoList().get((int)oIdx);
                        return MaxLocationInfo.create(shInfo,(int)oIdx);
                    });

                    if(EmptyChecker.isEmpty(resultList)){

                        setLastMax(maxParamInfo.getMaxLast(),maxParamInfo.getMinLast(),maxParamInfo.getLastMax(),maxTmpList);

                        if (index < maxTmpList.get(0).getIndex()){
                            index = maxTmpList.get(0).getIndex();
                            maxParamInfo.add(maxTmpList.get(0));
                            setDiffDrop(maxTmpList.get(0),maxTmpList.get(1),maxParamInfo);
                        } else {
                            maxParamInfo.add(maxTmpList.get(0));
                            setDiffDrop(maxTmpList.get(0),maxTmpList.get(1),maxParamInfo);
                            maxParamInfo.add(maxTmpList.get(1));
                        }

                    }else {
                       StockMaxInfo last =(StockMaxInfo)RxUtil.ListUtil.getLast(resultList);

                       if (MAX_FLG.MAX.getCode().equalsIgnoreCase(last.getMaxFlg())){
                           // 入库是高点
                           if (MAX_FLG.MIN.getCode().equalsIgnoreCase(maxTmpList.get(0).getMaxFlg())){
                               // 第一个是低点。
                               // 更换低点
                               maxParamInfo.changeMinLast(maxTmpList.get(0));

                               // 最近确定入口的极值点与第一个点之间是否有较大起伏
                               setDiffDrop(maxParamInfo.getLastMax(),maxTmpList.get(0),maxParamInfo);

                               // 将第一个点加入
                               maxParamInfo.add(maxTmpList.get(0));

                               // 第二个低点肯定比第以前的低点低
                               maxParamInfo.setMaxLast(maxTmpList.get(1));


                           }else{
                               // 第一个是高点
                               if (maxParamInfo.yesMax(maxTmpList.get(0))){
                                   maxParamInfo.changeMinLast(maxTmpList.get(1));
                               }else {

                                   // 追不上遍历点
                                   if (maxParamInfo.getLastMax().getIndex() < index){
                                       if (maxParamInfo.getMinLast().getIndex() < maxTmpList.get(0).getIndex()){

                                           MaxLocationInfo smaller = getPeek(stockHistoryInfoList,maxParamInfo.getMinLast().getIndex(),maxTmpList.get(0).getIndex(),false);
                                           maxParamInfo.add(smaller);
                                           maxParamInfo.add(maxTmpList.get(0));
                                           maxParamInfo.setMaxLast(maxTmpList.get(0));
                                       }

                                       maxParamInfo.setMinLast(maxTmpList.get(1));

                                   }else{
                                       MaxLocationInfo tmp = maxParamInfo.getMinLast();
                                       // 最近到低点
                                       setDiffDrop(maxParamInfo.getLastMax(),tmp,maxParamInfo);

                                       maxParamInfo.add(tmp);

                                       maxParamInfo.setMaxLast(maxTmpList.get(0));

                                       // 最近到第一个点
                                       setDiffDrop(maxParamInfo.getLastMax(),maxTmpList.get(0),maxParamInfo);

                                       maxParamInfo.add(maxTmpList.get(0));

                                       maxParamInfo.setMinLast(maxTmpList.get(1));
                                   }


                               }
                           }
                       }else {
                           // 低点
                           if (MAX_FLG.MAX.getCode().equalsIgnoreCase(maxTmpList.get(0).getMaxFlg())){
                               // 第一个是高点。

                               // 更换高点
                               maxParamInfo.changeMaxLast(maxTmpList.get(0));

                               // 最近确定入口的极值点与第一个点之间是否有较大起伏
                               setDiffDrop(maxParamInfo.getLastMax(),maxTmpList.get(0),maxParamInfo);

                               // 将第一个点加入
                               maxParamInfo.add(maxTmpList.get(0));

                               // 第二个低点肯定比第以前的低点低
                               maxParamInfo.setMinLast(maxTmpList.get(1));

                           }else{
                               // 第一个是低点

                               // 第一个是高点
                               if (maxParamInfo.yesMin(maxTmpList.get(0))){
                                   maxParamInfo.changeMaxLast(maxTmpList.get(1));
                               }else {

                                   if (maxParamInfo.getLastMax().getIndex() < index){
                                       if (maxParamInfo.getMaxLast().getIndex() < maxTmpList.get(0).getIndex()){

                                           MaxLocationInfo bigger = getPeek(stockHistoryInfoList,maxParamInfo.getMaxLast().getIndex(),maxTmpList.get(0).getIndex(),true);
                                           maxParamInfo.add(bigger);
                                           maxParamInfo.add(maxTmpList.get(0));
                                           maxParamInfo.setMinLast(maxTmpList.get(0));
                                       }

                                       maxParamInfo.setMaxLast(maxTmpList.get(1));
                                   }else{
                                       MaxLocationInfo tmp = maxParamInfo.getMaxLast();
                                       // 最近到低点
                                       setDiffDrop(maxParamInfo.getLastMax(),tmp,maxParamInfo);

                                       maxParamInfo.add(tmp);

                                       maxParamInfo.setMinLast(maxTmpList.get(0));

                                       // 最近到第一个点
                                       setDiffDrop(maxParamInfo.getLastMax(),maxTmpList.get(0),maxParamInfo);

                                       maxParamInfo.add(maxTmpList.get(0));

                                       maxParamInfo.setMaxLast(maxTmpList.get(1));
                                   }


                               }

                           }
                       }

                    }

                    if(index == maxTmpList.get(0).getIndex()){
                        index = maxTmpList.get(1).getIndex();
                    }else {
                        index = maxTmpList.get(0).getIndex();
                    }
                }


                dealIsUpdateForMax(mapListFormDb,resultList,MAX_TYPE.N.getCode());

                return resultList;
            });

            if (EmptyChecker.isEmpty(resultList)){
                return;
            }

            List<RxBaseData> allMaxList = resultList.stream().filter(e->{
                StockMaxInfo infos = (StockMaxInfo)e;
                return MAX_FLG.MAX.getCode().equalsIgnoreCase(infos.getMaxFlg());
            }).collect(Collectors.toList());

            dealOneShareMax(stockShareInfo,MAX_TYPE.S.getCode(),maxObjects->{
                return dealMaxWithRate(allMaxList,maxObjects,stockShareInfo,MAX_TYPE.S.getCode(),minChangeRate);
            });

            dealOneShareMax(stockShareInfo,MAX_TYPE.S.getCode(),maxObjects->{
                return dealMaxWithRate(allMaxList,maxObjects,stockShareInfo,MAX_TYPE.B.getCode(),"0.5");
            });
        });
    }
    public Object runMax(){
        asyncTask.runMax();
        return Integer.valueOf(0);
    }

    public Object getSzsSomething(){

        String requestUrl = "http://www.szse.cn/api/report/ShowReport/data?SHOWTYPE=JSON&CATALOGID=1110&TABKEY=tab1&PAGENO=1&tab1PAGESIZE=5000";
        Map<String, String> requestUrlParam = new HashMap<>();
        //licence
        requestUrlParam.put("licence", rxStockLicence);
        //发送post请求读取调用微信接口获取openid用户唯一标识
        //发送post请求读取调用微信接口获取openid用户唯一标识{"dm":"000001","jys":"sz","mz":"平安银行"}
        String json = HttpClientUtil.doGet(requestUrl, requestUrlParam);

        List<NetShareInfoFromsz> list = JSONArray.parseArray(json, NetShareInfoFromsz.class);
        if(EmptyChecker.isEmpty(list)){
            return 0;
        }

        List<NetShareInfoFromsz.MetaInfo> metaInfos = list.get(0).getData();

        if (EmptyChecker.isEmpty(metaInfos)){
            return  0;
        }
        Map<String,List<NetShareInfoFromsz.MetaInfo>> map = metaInfos.stream()
                .collect(Collectors.groupingBy(NetShareInfoFromsz.MetaInfo::getAgdm));


        try {
            // 查询所有股票
            RxBaseData conditionForQuery = RxBaseData.create(StockShareInfo.class, HANDLER_TYPE.SINGLE_LIST);
            Object object = standardService.searchList(conditionForQuery);
            if (object instanceof List){
                List<RxBaseData> stockShareInfoList = new ArrayList<>();
                List<StockShareInfo> haveInDbList = (ArrayList<StockShareInfo>)object;
                for (RxBaseData rxBaseData : haveInDbList) {
                    StockShareInfo netShareInfo = (StockShareInfo)rxBaseData;
                    List<NetShareInfoFromsz.MetaInfo> metaInfo= map.get(netShareInfo.getShareCode());
                    if(EmptyChecker.notEmpty(metaInfo)){
                        netShareInfo.setYkl(metaInfo.get(0).getSshymc());
                        netShareInfo.setNegotiableCapital(metaInfo.get(0).getAgzgb().multiply(new BigDecimal(10000)));

                        stockShareInfoList.add(netShareInfo);
                    }
                }

                RxBaseData condition = RxBaseData.create(StockShareInfo.class, HANDLER_TYPE.SINGLE_BATCH_SAVE);
                condition.setDataList(stockShareInfoList);
                standardService.batchSave(condition);
            }



        } catch (IllegalAccessException | InstantiationException e)  {
            log.info(e.getMessage());
        }

        return Integer.valueOf(0);
    }
}
